<?php

/*******  2.5 在指定范围内生成随机数  *****************/

// 问题

// 希望在指定的数字范围内生成一个随机数

// 解决方案
/*************************************************
 * 使用 mt_rand($min,$max)：int 速度比 rand() 快
 ************************************************/


$lower = 10;
$upper = 100;
$randomNumber = mt_rand($lower, $upper);//int(67)


/*******  2.6 生成可预测的随机数  *****************/

// 问题
// 希望生成可预测的随机数，从而可以保证可重复的行为

// 解决方案

/****************************************************************
 * 使用 mt_srand()/ srand()
 * 为随机数生成器提供一个已知值作为种子
 * 作用 每次运行测试时，就可以确保每次运行测试时生成的随机序列时相同的
 * 反之 每次的随机数返回都不一样
 *****************************************************************/

function pick_color()
{
    $colors = [
        'red',
        'orange',
        'yellow',
        'blue',
        'green',
        'indigo',
        'violet'
    ];
    $i = mt_rand(0, count($colors) - 1);
    return $colors[$i];
}


//mt_srand(3);
$first = pick_color();
$second = pick_color();

//print "$first is xxx and $second is sss";


/*******  2.7 生成偏随机数  *****************/

// 问题
// 希望生成随机数，但是又希望这些数有些偏向性，使某个范围内的数出现频率高于其他的数，
// 例如，希望根据每个广告活动的剩余访问数来推广一系列横幅广告

// 解决方案

/****************************************************************
 * rand_weighted()
 *
 *****************************************************************/

function rand_weighted($numberArr)
{
    $total = 0;
    foreach ($numberArr as $number => $weight) {
        $total += $weight;
        $distribution[$number] = $total;
        //     var_dump($distribution[$number]);
    }

    // echo "==============total  $total =========\n";
    $rand = mt_rand(0, $total - 1);
    //  echo "=============== rand  ================\n";
    // var_dump($rand);

    // echo "=============== weights  ================\n";
    foreach ($distribution as $number => $weights) {

        if ($rand < $weights) {
            return $number;
        }
    }
}

$ads = [
    'ford' => 12234,
    'att' => 33424,
    'ibm' => 16823
];

$ad = rand_weighted($ads);


function incremental_total($numberArr)
{
    $total = 0;
    foreach ($numberArr as $number => $weight) {
        $total += $weight;
        //var_dump($number);
        yield $number => $total;
    }
}

function rand_weighted_generator($numbers)
{
    $total = array_sum($numbers);
    $rand = mt_rand(0, $total - 1);
    foreach (incremental_total($numbers) as $number => $weight) {
        if ($rand < $weight) {
            return $number;
        }
    }
}

$res = rand_weighted_generator($ads);
//echo "============ result =========\n";
//var_dump($res);


/*******  2.10 格式化数字  *****************/

// 问题
// 希望输出一个数，要包括 千位分隔符和小数点
// 如：显示访问一个页面的人数/显示这些的百分比

// 解决方案

/****************************************************************
 * 如果总是需要小数点和千位分隔符等特定字符
 * 使用 number_format()
 * 格式化一个数，默认整个数舍人到最近的整数
 *
 * 世界上任何地方的数字 格式化 可用 NumberFormatter 类
 *****************************************************************/


$number = 1234878.5624501589;

// 保留 4 位小数点， 千位以 逗号 分隔
$formatted1 = number_format($number, 4, '.', ',');
//string(14) "1,234,878.5625"

// 如果想保留整个数，但无法提前知道小数点后有多少位

list($int, $dec) = explode('.', $number);
$formatted = number_format($number, strlen($dec));
//string(17) "1,234,878.5624502"

$france = new NumberFormatter('fr-FR', NumberFormatter::SPELLOUT);
$france->format($number);


/*******  2.11 格式化货币值  *****************/

// 解决方案

// 使用 NumberFormatter 类 NumberFormatter::CURRENCY

$money = 1234.56;
// 美国
$usa = new NumberFormatter("en-US", NumberFormatter::CURRENCY);
$moneyUs = $usa->format($number);

// 法国
$francy = new NumberFormatter("fr-FR", NumberFormatter::CURRENCY);
$moneyF = $francy->formatCurrency($number, 'EUR');
